package com.sixbro.common.domain;

import lombok.Getter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * </p>
 *
 * @author: Mr.Lu
 * @since: 2021/11/2 15:27
 */
@Getter
public class Principal implements UserDetails {

    private String id;
    private String username;
    private String password;
    private boolean accountNonExpired = true;
    private boolean accountNonLocked = true;
    private boolean credentialsNonExpired = true;
    private boolean enabled = true;

    private Set<Role> roles = new HashSet<>( );

    private Scope scope;

    private Principal( String username ) {
        this.username = username;
    }

    public static Principal create(String id, String username, String password, Set<Role> roles, Scope scope) {
        Principal principal = new Principal( username )
                .setId(id)
                .setPassword(password)
                .setRoles(roles)
                .setScope(scope);
        return principal;
    }

    public static Principal anonymousRefreshToken( String username ) {
        return new Principal( username );
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if ( roles == null ) {
            return Collections.emptySet( );
        }
        Collection<SimpleGrantedAuthority> authorities = new HashSet<>( );
        roles.forEach( role -> {
            Collection< SimpleGrantedAuthority > collect = role.getPrivileges( ).stream( )
                    .map( privilege -> new SimpleGrantedAuthority( privilege.getPrivilege( ) ) )
                    .collect( Collectors.toList( ) );
            authorities.addAll( collect );
        } );
        return authorities;
    }

    public Principal setId(String id) {
        this.id = id;
        return this;
    }

    public Principal setUsername(String username) {
        this.username = username;
        return this;
    }

    public Principal setPassword(String password) {
        this.password = password;
        return this;
    }

    public Principal setRoles(Set<Role> roles) {
        this.roles = roles;
        return this;
    }

    public Principal setScope(Scope scope) {
        this.scope = scope;
        return this;
    }
}
